#ifndef _FPDF_LR_H_
#define _FPDF_LR_H_

#include "fpdflr_taggedhandler.h"

class IPDFLR_Cell;
class IPDFLR_Attribute;
class IPDFLR_PageProcessor;

typedef enum _FPDFLR_ProgressiveStatus
{
	FPDFLR_ProgressiveStatus_Ready,
	FPDFLR_ProgressiveStatus_ToBeContinued,
	FPDFLR_ProgressiveStatus_Done,
	FPDFLR_ProgressiveStatus_Failed
} FPDFLR_ProgressiveStatus;

/** Define values of content order in  class CPDFLR_ParseOptions */
#define	FPDFLR_PARSERFLAG_STREAM_ORDER	0x0001
#define FPDFLR_PARSERFLAG_POSITION_ORDER 0x0002

/** Define values of writing mode in  class CPDFLR_ParseOptions */
#define	FPDFLR_PARSERFLAG_HORIZIONTAL_WRITINGMODE	0x0000
#define FPDFLR_PARSERFLAG_VERTICAL_WRITINGMODE		0x0001

class CPDFLR_ParseOptions : public CFX_Object
{
public:
	CPDFLR_ParseOptions() : m_WritingMode(0)
		, m_ContentOrder(0)
		, m_Rotation(0)
		, m_PageRect()
		, m_TextOnly(FALSE)
	{
	}

	FX_INT32		m_WritingMode;
	FX_INT32		m_ContentOrder;                  
	FX_INT32		m_Rotation;
	FX_BOOL			m_TextOnly;
	CPDF_Rect		m_PageRect;				
};

class IPDFLR_DocumentProcessor
{
public:
	static	IPDFLR_DocumentProcessor*	Create();

	virtual ~IPDFLR_DocumentProcessor() {}
	
	virtual  FX_BOOL					Initialize(CPDF_Document* pDoc, CPDFLR_ParseOptions* pParseOption = NULL) = 0;

	virtual  IPDFLR_PageProcessor*		GetPageProcessor(FX_INT32 nPageIndex) = 0;
	virtual  IPDFLR_PageProcessor*		GetPageProcessor(CPDF_Page* pPage) = 0;
	
	virtual  IPDFLR_Cell*				GetRootCell() = 0;
};

class IPDFLR_PageProcessor
{
public:
	virtual CPDF_Page*					GetPDFPage() const = 0;

	virtual FPDFLR_ProgressiveStatus	Start(FX_BOOL bReparse, CPDFLR_ParseOptions* pParseOption = NULL) = 0;
	virtual FPDFLR_ProgressiveStatus	Continue(IFX_Pause* pPause) = 0;
	
	virtual IPDFLR_Cell*				GetRootCell() = 0;

	virtual FX_INT32					CountLines() = 0;
	virtual IPDFLR_Cell*				GetLine(FX_INT32) = 0;

	virtual FX_INT32					CountCatalog() = 0;
	virtual IPDFLR_Cell*				GetCatalog(FX_INT32) = 0;

	virtual FX_INT32					CountParagraphs() = 0;
	virtual IPDFLR_Cell*				GetParagraph(FX_INT32) = 0;

	virtual void						Clear() = 0;
};

class IPDFLR_Attribute
{
public:
	virtual FX_INT32					CountLayoutAttrs() = 0;

	virtual FPDFLR_Attribute			GetLayoutAttr(FX_INT32 index) = 0;
	virtual FPDFLR_AttributeValues		GetEnumAttr(FPDFLR_Attribute attr_type) = 0;
	virtual FX_FLOAT					GetFloatAttr(FPDFLR_Attribute attr_type) = 0;
	virtual FX_INT32					GetIntegerAttr(FPDFLR_Attribute attr_type) = 0;
	virtual FX_ARGB						GetColorAttr(FPDFLR_Attribute attr_type) = 0;
	virtual CPDF_Rect					GetRectangleAttr(FPDFLR_Attribute attr_type) = 0;
	virtual CFX_Matrix					GetMatrixAttr(FPDFLR_Attribute attr_type) = 0;
};

class IPDFLR_Cell
{
public:
	virtual void					Release() = 0;

	virtual IPDFLR_Cell*			GetParent() const = 0;
	virtual FPDFLR_AttributeType	GetCellType() const = 0;
	virtual void					GetBBox(CPDF_Rect& bbox) const = 0;
	virtual CPDF_PageObject*		GetPageObject() const = 0;
	virtual CFX_Matrix				GetMatrix() const = 0;

	virtual IPDFLR_Attribute*		GetLayoutAttrs() = 0;

	virtual FX_INT32				CountChildCells() = 0;
			FX_BOOL					IsLeaf() {return CountChildCells() == 0;}
	virtual FX_POSITION				GetChildCellHeadPos() = 0;
	virtual FX_POSITION				GetChildCellTailPos() = 0;
	virtual FX_POSITION				GetChildCellPrevPos(FX_POSITION pos) = 0;
	virtual FX_POSITION				GetChildCellNextPos(FX_POSITION pos) =0;
	virtual FX_POSITION				GetChildCellPos(IPDFLR_Cell* pCell) = 0;
	virtual IPDFLR_Cell*			GetNextChildCell(FX_POSITION& pos) = 0;
	virtual IPDFLR_Cell*			GetPrevChildCell(FX_POSITION& pos) = 0;

	virtual FX_POSITION				AddChildCellHead(IPDFLR_Cell* pNewCell, FX_BOOL bUpdateBBox) = 0;
	virtual FX_POSITION				AddChildCellTail(IPDFLR_Cell* pNewCell, FX_BOOL bUpdateBBox) = 0;
	virtual FX_POSITION				InsertChildCellAfter(FX_POSITION pos, IPDFLR_Cell* pNewCell, FX_BOOL bUpdateBBox) = 0;
	virtual FX_POSITION				InsertChildCellBefore(FX_POSITION pos, IPDFLR_Cell* pNewCell, FX_BOOL bUpdateBBox) = 0;
	virtual IPDFLR_Cell*			DeleteChildCell(FX_POSITION pos, FX_BOOL bUpdateBBox) = 0;
	virtual	void					DestroyChildren() = 0;

	virtual void					UpdateBBox() = 0;
};

#endif
